'use strict';

/**
 * @ngdoc function
 * @name consoleAngularUiApp.service:auth
 * @description
 * # ServService
 * Cloud Auth service of the consoleAngularUiApp
 */
angular.module('consoleAngularUiApp').factory('$authServ', ['$http', '$base64', '$plUtils', function ($http, $base64, $plUtils) {

	var PLCM = 'PLCM';

	var loginRst = {
		user: null,
		rolePermission: null,
		successInfo: {},
		failInfo: {}
	};

	var login = function (username, password) {
		if (!username || !password) {
			throw new Error('you must specify usernaem and password.');
		}

		var u = new String(username).trim();
		var p = new String(password).trim();
		var encodePwd = $base64.encode(p);
		var url = '/api/rest/rprm/login/login';

		var config = {
			headers: {
				'Accept': 'application/vnd.plcm.plcm-user-login-detail+json',
				'X-CA-Password': encodePwd,
				'X-CA-UserName': u,
				'X-CA-Domain': 'LOCAL'
			}
		}

		return $http.post(url, null, config)
					.success(function (res) {
						loginRst.user = res['plcm-user'];
						loginRst.rolePermission = res['plcm-user-role-permission-list']['plcm-user-role-permission'];
						loginRst.successInfo['last-login-date'] = res['last-login-date'];
						loginRst.successInfo['last-login-location'] = res['last-login-location'];
						loginRst.failInfo['last-fail-login-date'] = res['last-fail-login-date'];
						loginRst.failInfo['last-fail-login-location'] = res['last-fail-login-location'];
						loginRst.failInfo['failed-login-attempts'] = res['failed-login-attempts'];
						loginRst.failInfo['failed-attempts-since-start'] = res['failed-attempts-since-start'];
						loginRst.failInfo['start-login-fail-date'] = res['start-login-fail-date'];

						$plUtils.cookies.set('t', encryptToken(res.token));
					})
	}

	var logout = function () {

	}

	var getCurrentUser = function () {
		return loginRst.user;
	}

	var getCurrentUserRolePermission = function () {
		return loginRst.rolePermission;
	}

	var getLastSuccessfulLoginInfo = function () {
		return loginRst.successInfo;
	}

	var getfailedLoginInfo = function () {
		return loginRst.failInfo;
	}

	var getToken = function () {
		var token = $plUtils.cookies.get('t');
		return decryptToken(token);
	}

	function encryptToken (token) {
		var separator = '-', r = [], weight = 0, rst = '';
		var arr = token.split(separator);
		_.each(PLCM, function (val, key) {
			r[key] = (key % 2 == 0)? val.charAt().charCodeAt() >> (key + 1) : val.charAt().charCodeAt() << (key + 1);
		})
		_.each(r, function (val) {
			weight += val;
		})
		_.each(arr, function (part, index) {
			var partRst = '';
			_.each(part, function (ch) {
				partRst = partRst.concat($plUtils.toHex(ch.charAt().charCodeAt() + weight));
			});
			if (index == 0) {
				rst = rst.concat(partRst);
			} else {
				rst = rst.concat(separator + partRst);
			}
		});

		return rst;
	}

	function decryptToken (token) {
		var separator = '-', r = [], weight = 0, rst = '';
		var arr = token.split(separator);
		_.each(PLCM, function (val, key) {
			r[key] = (key % 2 == 0)? val.charAt().charCodeAt() >> (key + 1) : val.charAt().charCodeAt() << (key + 1);
		})
		_.each(r, function (val) {
			weight += val;
		})
		_.each(arr, function (part, index) {
			var partRst = '';
			var partNum = _.without(part.split('0x'), '');
			_.each(partNum, function (num) {
				partRst = partRst.concat(String.fromCharCode(Number.parseInt('0x' + num) - weight));
			});
			if (index == 0) {
				rst = rst.concat(partRst);
			} else {
				rst = rst.concat(separator + partRst);
			}
		})

		return rst;
	}

	return {
		login: login,
		logout: logout,
		currentUser: getCurrentUser,
		currentUserRolePremission: getCurrentUserRolePermission,
		lastSuccessfulLoginInfo: getLastSuccessfulLoginInfo,
		failedLoginInfo: getfailedLoginInfo,
		token: getToken
	}
}])